-- 所有设备的集合
-- 开关设备 0为关，1为开
-- 水压设备 
-- 陀螺仪 判断倾斜角是否大于30度 0为否，1为是
-- 电池电压

local device_gyroscope = require "device_gyroscope"
local device_pressure = require "device_pressure"

local gpio_switch_pin = 21
local current_switch_status = 0
local current_pressure_status = 0
local current__euler_angles_status = 0
local current_vbat_status = 0
local dup_report_file = "/dup_report_file.json"

-- 写入dup_report_file
local report_table = {}

if utils.isFirstBoot() then
    report_table = {
        switch = {
            value = -1,
            time = nil
        },
        pressure = {
            value = -1,
            time = nil
        },
        euler_angles = {
            value = -1,
            time = nil
        },
        vbat = {
            value = -1,
            time = nil
        }
    }
    io.writeFile(dup_report_file, json.encode(report_table))
end

local function init_devices()
    -- 开关设备初始化
    gpio.setup(gpio_switch_pin, nil, gpio.PULLUP)
    -- 配置输入检测防抖50ms
    gpio.debounce(gpio_switch_pin, 50) 
    -- 压力设备初始化
    adc.setRange(adc.ADC_RANGE_MAX) 
end

local function get_switch()
    local data = gpio.get(gpio_switch_pin)
    if data then
        log.info("当前开关 status of switch:", data)
        return data
    end
    log.info("ERROR: when read status of switch")
    return nil
end

local function get_pressure()
    local pressure = device_pressure.get()
    log.info("当前压力 value of pressure:",pressure)
    return pressure
end

-- 电压读取adc 1
local function get_vbat()
    adc.open(adc.CH_VBAT)
    local vbat = adc.get(adc.CH_VBAT)
    log.info("当前电压value of vbat: ", vbat)
    adc.close(adc.CH_VBAT)
    return vbat
end

-- 获取所有设备的数据
local function get_all()
    local switch_data = get_switch()
    local pressure_data = get_pressure()
    local gyroscope_data = device_gyroscope.get() -- 返回0 or 1
    local vbat_data = get_vbat()
    return switch_data, pressure_data,gyroscope_data,vbat_data
end

-- 如果switch的值发生改变则上报,循环任务
local function report()
    sys.waitUntil("CONFIG_READY")
    log.info("switch report data")
    sys.waitUntil("mqtt_conack")
    result = {}
    local swtich_data,pressure_data,gyroscope_data,vbat_data = get_all()
    log.info("获取设备数据：",swtich_data,pressure_data,gyroscope_data,vbat_data)
    local device_status = json.decode(io.readFile(dup_report_file))
    local ts = os.time()
    -- 开关变化报警
    if swtich_data then
        -- 状态改变上报
        if swtich_data ~= device_status['switch'].value then
            result['switch'] = swtich_data
        -- 连续报警状态，只有超过时间阈值才上报
        elseif swtich_data == 1 and os.difftime(ts, device_status['switch'].time) > interval.dup_no_report then
            result['switch'] = swtich_data
        end
        log.debug("   现在开关状态:"..swtich_data, "之前开关状态:".. device_status['switch'].value)            
        device_status['switch'].value = swtich_data
        device_status['switch'].time = ts
    end
    -- 水压高于阈值报警
    if pressure_data then
        local pressure_status = 0
        if pressure_data > threshold.pressure then
            pressure_status = 1 -- 报警状态
        end
        -- 状态改变上报
        if pressure_status ~= device_status['pressure'].value then
            result['pressure'] = pressure_data
        -- 连续报警状态，只有超过时间阈值才上报
        elseif pressure_status == 1 and os.difftime(ts, device_status['pressure'].time) > interval.dup_no_report then
            result['pressure'] = pressure_data
        end
        log.debug("   现在压力状态-值:"..pressure_status, pressure_data, "之前压力状态:".. device_status['pressure'].value, "阈值:"..threshold.pressure)            
        device_status['pressure'].value = pressure_status
        device_status['pressure'].time = ts
    end
    -- 倾斜角变化或状态改变报警
    if gyroscope_data then
        -- 状态改变上报
        if gyroscope_data ~= device_status['euler_angles'].value then -- 倾斜角的逻辑在device_gyroscope.lua实现,1代表发生倾斜
            result['euler_angles'] = gyroscope_data
        elseif gyroscope_data == 1 and os.difftime(ts, device_status['euler_angles'].time) > interval.dup_no_report then
            result['euler_angles'] = gyroscope_data
        end
        log.debug("   现角度状态："..gyroscope_data,"阈值"..threshold.euler_angles.."度")
        device_status['euler_angles'].value = gyroscope_data
        device_status['euler_angles'].time = ts
    end
    if vbat_data then
        local vbat_status = 0
        if vbat_data < threshold.vbat then
            vbat_status = 1 -- 报警状态
        end
        -- 状态改变上报
        if vbat_status ~= device_status['vbat'].value then
            result['vbat'] = vbat_data
        -- 连续报警状态，只有超过时间阈值才上报
        elseif vbat_status == 1 and os.difftime(ts, device_status['vbat'].time) > interval.dup_no_report then
            result['vbat'] = vbat_data
        end
        log.debug("   现在电池电压状态-值:".. vbat_status, vbat_data, "之前电压状态:".. device_status['vbat'].value, "阈值:"..threshold.vbat)            
        device_status['vbat'].value = vbat_status
        device_status['vbat'].time = ts
    end
    io.writeFile(dup_report_file, json.encode(device_status))
    -- 如果不满足条件，就不会向result里加数据，result的长度为0
    if utils.table_len(result) > 0 then
        utils.addLatLng(result)
        result['pressure'] = pressure_data -- 无论如何都上报压力值
        log.info("准备上报的数据", json.encode(result))
        sys.publish("MQTT_PUB2", result)
    else
        log.info("本次数据在无变化，不上传数据，进入休眠")
        utils.psm()
    end
end


sys.taskInit(init_devices)

sys.taskInit(report)
